package com.batchengine.service;

import com.batchengine.manager.SystemWorkerManager;
import com.batchengine.manager.UserWorkerManager;
import com.batchengine.manager.WorkerManager;
import com.batchengine.schedular.CronSchedularWorkerManager;
import com.batchengine.util.ControlPortHelper;
import static com.batchengine.util.ControlPortHelper.*;
import static com.batchengine.util.LoggingFactory.createLogger;
import org.apache.log4j.Logger;

import java.io.PrintWriter;
import static java.lang.System.exit;
import static java.util.Collections.synchronizedMap;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by sunil.incubator@yahoo.com.
 * User: sunil.kalva
 * Date: Jun 21, 2009
 */
public class BatchEngineService extends ServiceImpl {

    public static int managerId = 0;

    private static final Logger logger = createLogger();

    private Map<Integer, WorkerManager> managerMap = synchronizedMap(new HashMap<Integer, WorkerManager>());

    protected boolean isManagerAlive(WorkerManager managerI) {
        return managerI.isStopped() && managerI.getNumberOfActiveWorkers() == 0;
    }

    protected int getNumberOfAliveManagers() {

        int ret = 0;
        for (Integer manger : managerMap.keySet()) {
            if (!isManagerAlive(managerMap.get(manger))) {
                ret++;
            }
        }
        return ret;
    }

    public void init() {
        ManagerUtil.startTaskManager(managerMap);
    }

    public boolean handleCommand(String commandName, String[] args, PrintWriter writer) {

        if (commandName.equalsIgnoreCase("close")) {
            return handleCloseCommand(writer);
        } else if (commandName.equalsIgnoreCase("DisplayUserManagers")) {
            return displayUserManagers(writer, false);
        } else if (commandName.equalsIgnoreCase("DisplayManager")) {
            return displayManager(writer, args[0], false);
        } else if (commandName.equalsIgnoreCase("DisplayPool")) {
            return displayPool(writer, args[0], args[1], false);
        } else if (commandName.equalsIgnoreCase("StopTask")) {
            return stopTask(writer, args[0], args[1], args[2], false);
        } else if (commandName.equalsIgnoreCase("kill")) {
            exit(0);
        } else if (commandName.equals("shutdown")) {
            return handleStopCommand(args, writer);
        } else if (commandName.equals("stop")) {
            return handleStopCommand(args, writer);
        } else if (commandName.equals("help")) {
            return ControlPortHelper.handleHelpCommand(args, writer, false);
        } else {
            return handleUnknownCommand(commandName, writer);
        }

        return false;
    }

    /**
     * This implementation always returns false.
     */
    public boolean requiresAuthentication() {
        return false;
    }

    public Map<Integer, WorkerManager> getManagers() {
        return managerMap;
    }

    private static class ManagerUtil {

        public static int startTaskManager(final Map<Integer, WorkerManager> managerMap) {

            final int taskId = getUniqueManagerId();
            new Thread("WorkerManager") {
                public void run() {

                    WorkerManager systemWorkerManager = new SystemWorkerManager("SystemWorkerManager");
                    managerMap.put(getUniqueManagerId(), systemWorkerManager);
                    systemWorkerManager.startManager();

                    WorkerManager userWorkerManager = new UserWorkerManager("UserWorkerManager");
                    managerMap.put(getUniqueManagerId(), userWorkerManager);
                    userWorkerManager.startManager();

//                    CronSchedularWorkerManager schedularWorkerManager = CronSchedularWorkerManager.getCronSchedular();
//                    managerMap.put(getUniqueManagerId(), schedularWorkerManager);
//                    schedularWorkerManager.startManager();
                }
            }.start();
            return taskId;
        }

        protected static int getUniqueManagerId() {
            return managerId++;
        }
    }
}
